//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef __CMODULE_H__
#define __CMODULE_H__

#include <elasys_server.h>
#include "objenum.h"
#include "cprocess.h"

#define _MAX_MODULE_PATH  260

class CModule : public ObjectEnumeratorNode, public IModule
{
public:
    CARAPI_(IInterface *) GetObject() { return (IModule *)this; }

public:
    CARAPI_(PInterface) Probe(
        /* [in]  */ REIID riid);

    CARAPI_(UInt32) AddRef();

    CARAPI_(UInt32) Release();

    CARAPI Aggregate(
        /* [in] */ AggrType aggrType,
        /* [in] */ PInterface pObject);

    CARAPI GetDomain(
        /* [out] */ PInterface *ppObject);

    CARAPI GetBaseAddress(
        /* [out] */ Address * pBase);

    CARAPI GetEntryPointAddress(
        /* [out] */ Address * pEntryPoint);

    CARAPI GetMemorySize(
        /* [out] */ MemorySize * pSize);

    CARAPI GetName(
        /* [out] */ WStringBuf * name);

    CARAPI GetFullPath(
        /* [out] */ WStringBuf * name);

    CARAPI GetProcAddressByName(
        /* [in] */ AString Name,
        /* [out] */ Address * pAddress);

    CARAPI GetProcAddressByOrdinal(
        /* [in] */ Int32 ordinal,
        /* [out] */ Address * pAddress);

    CARAPI GetResourceSection(
        /* [out] */ Address * pAddress);

    CARAPI GetSectionByName(
        /* [in] */ AString Name,
        /* [out] */ Address * pAddress);

    CARAPI FindResource(
        /* [in] */ WString wsName,
        /* [in] */ WString wsType,
        /* [out] */ Address * pAddress,
        /* [out] */ MemorySize * pSize);

public:
    CModule(PVoid moduleListLock)
           :m_hModule(NULL),
            m_baseAddr(0),
            m_entryPoint(0),
            m_sizeOfImage(0),
            m_moduleListLock(moduleListLock)
            {DLinkNode::Initialize();}

    virtual ~CModule();

    ECode Constructor(
        /* [in] */ WString name,
        /* [in] */ ModuleLoadFlags flags);

public:
    static ECode New(
        /* [in] */ WString name,
        /* [in] */ ModuleLoadFlags flags,
        /* [in] */ PVoid moduleListLock,
        /* [out] */ IModule ** ppModule);

private:
    friend  class CProcess;
    PVoid   m_hModule;

    wchar_t m_name[_MAX_MODULE_PATH];
    wchar_t m_path[_MAX_MODULE_PATH];

    Address m_baseAddr;
    Address m_entryPoint;
    MemorySize m_sizeOfImage;

    PVoid   m_moduleListLock;

private:
    Interlocked m_cRef;
};

#endif //__CMODULE_H_

